﻿using System;
using System.Collections.Generic;
using System.Linq;
using Domaine;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;

/// Morgan Leroi - http://coding-in.net
/// http://coding-in.net/fr/tout-savoir-ou-presque-sur-le-behaviour-driven-development-bdd/
namespace BDD
{
    [Binding]
    public class CasDeTest
    {
        private readonly ContexteMagasin _contexte;
        private readonly ContexteCommun _contexteCommun;

        public CasDeTest(ContexteMagasin contexte, ContexteCommun contexteCommun)
        {
            _contexte = contexte;
            _contexteCommun = contexteCommun;
        }

        [Given(@"Le catalogue du magasin est")]
        public void GivenLeStockDuMagasinEst(Table table)
        {
            _contexte.Magasin = new Magasin { Stock = table.CreateSet<Produit>() };
        }

        [Given(@"(.*) (.*), client du site")]
        public void GivenMorganLeroiClientDuSite(string prenom, string nom)
        {
            _contexte.Client = new Client(prenom, nom);
        }

        [When(@"Le client ajoute les articles au panier")]
        public void WhenLeClientAjouteLesArticlesAuPanier(Table table)
        {
            _contexte.Client.Panier = RemplirUnPanier(table);
        }

        [When(@"Le client valide le panier")]
        public void WhenLeClientValideLePanier()
        {
            try
            {
                _contexte.Client.Panier.ValiderLePanier();
            }
            catch (Exception ex)
            {
                _contexteCommun.Exception = ex;
            }
        }

        private Panier RemplirUnPanier(Table table)
        {
            var produits = new List<ProduitDuPanier>();
            table.Rows.ToList().ForEach(x =>
            {
                if (!string.IsNullOrEmpty(x["Produit"]) && !string.IsNullOrEmpty(x["Quantite"]))
                    produits.Add(new ProduitDuPanier
                    {
                        Produit =
                            _contexte.Magasin.Stock.Single(
                                y => y.Nom == x["Produit"]),
                        Quantite = int.Parse(x["Quantite"])
                    });
            });
            return new Panier { Produits = produits };
        }

        [Then(@"le montant total du panier est (.*)€")]
        public void ThenLeMontantTotalDuPanier(decimal montant)
        {
            Assert.AreEqual(montant, _contexte.Client.Panier.Total);
        }

        [Then(@"Un message d'erreur apparait : \""(.*)\""")]
        public void ThenLeMontantTotalDuPanier(string message)
        {
            Assert.AreEqual(message, _contexteCommun.Exception.Message);
        }

        [Then(@"le catalogue du magasin est")]
        public void ThenLeCatalogueDuMagasinEst(Table table)
        {
            VerifierLeStock(table);
        }

        private void VerifierLeStock(Table table)
        {
            table.CreateSet<Produit>().ToList().ForEach(prod =>
            {
                var produit = _contexte.Magasin.Stock.Single(x => x.Nom == prod.Nom);
                Assert.AreEqual(prod.Stock, produit.Stock);
            });
        }
    }
}